package com.zzld.modules.autoinn.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.abel533.entity.Example;
import com.zzld.core.sms.SenderSms;
import com.zzld.core.utils.Base64Coder;
import com.zzld.core.utils.CookieUtils;
import com.zzld.core.utils.EmojiFilter;
import com.zzld.core.utils.UuidUtil;
import com.zzld.modules.autoinn.entity.Collar;
import com.zzld.modules.autoinn.entity.Coupon;
import com.zzld.modules.autoinn.entity.Customer;
import com.zzld.modules.autoinn.entity.Expense;
import com.zzld.modules.autoinn.service.ICollarService;
import com.zzld.modules.autoinn.service.IConponService;
import com.zzld.modules.autoinn.service.ICustomerService;
import com.zzld.modules.autoinn.service.IExpenseService;
import com.zzld.modules.wechat.WeChat;
import com.zzld.modules.wechat.bean.UserInfo;
import com.zzld.modules.wechat.oauth.Oauth;
import com.zzld.modules.wechat.oauth.User;
import com.zzld.modules.wxsys.entity.WXAccount;
import com.zzld.modules.wxsys.entity.WXaccesstoken;
import com.zzld.modules.wxsys.service.IWXAccesstokenService;
import com.zzld.modules.wxsys.service.IWXAccountService;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/weixin/f/autoinn/user")
public class WXUserController
{
  private String userInfourl = "/wx/autoinn/account";
  private String loginurl = "/wx/autoinn/login";

  @Autowired
  private IWXAccountService wxAccountService;

  @Autowired
  private ICustomerService customerService;

  @Autowired
  private IWXAccesstokenService wxaccesstokenService;

  @Autowired
  private IConponService couponService;

  @Autowired
  private ICollarService collarService;

  @Autowired
  private IExpenseService expenseService;

  @RequestMapping(method={org.springframework.web.bind.annotation.RequestMethod.GET})
  public String wxuser(Model model, HttpServletRequest request) { return this.loginurl; }


  @RequestMapping({"/userInfo"})
  public String userInfo(HttpServletRequest request, HttpSession session, ModelMap modelmap, Model model, HttpServletResponse response)
  {
	 
    String openid = CookieUtils.getCookie(request, "autoinn_session");
    String wxaccount = CookieUtils.getCookie(request, "wx_session");
    try {
    	/*CookieUtils.setCookie(response, "wx_session", 
   			  Base64Coder.encoded("12312321"));
   	  CookieUtils.setCookie(response, "autoinn_session", 
   			Base64Coder.encoded("123"));*/
      openid = Base64Coder.decode(openid);
      wxaccount = Base64Coder.decode(wxaccount);
    } catch (Exception e1) {
      e1.printStackTrace();
    }

    if ((StringUtils.isNotBlank(wxaccount)) && 
      (StringUtils.isNotBlank(openid))) {
      try {
        Customer entity = this.customerService.findCustomer(wxaccount, 
          openid);

        if (entity != null) {
          if (request.getParameter("quan") != null)
            modelmap.addAttribute("quan", 
              request.getParameter("quan"));
          else {
            modelmap.addAttribute("quan", "");
          }

          Map<String,Object> masp = new HashMap<String,Object>();
          masp.put("wxaccount", wxaccount);
          masp.put("customerid", entity.getCustomerId());
          List<Expense> elist = this.expenseService.selectbydinglist(masp);

          Map<String,Object>  map = new HashMap<String,Object> ();
          map.put("nowtime", new Date());
          map.put("wcaccount", wxaccount);
          map.put("openid", openid);
          List<Coupon> list1 = this.couponService.selectbyzhifu(map);
          entity.setCoupon(Integer.valueOf(list1.size()));
          entity.setDing(Integer.valueOf(elist.size()));
          System.out.println(entity.getDing());
          modelmap.addAttribute("customer", entity);
          return this.userInfourl;
        }
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }
    return this.loginurl;
  }

  @RequestMapping("/gouserInfo")
  public String gouserInfo(HttpServletRequest request, HttpSession session, ModelMap modelmap, Model model)
  {
    String openid = CookieUtils.getCookie(request, "autoinn_session");
    String wxaccount = CookieUtils.getCookie(request, "wx_session");
    try {
      openid = Base64Coder.decode(openid);
      wxaccount = Base64Coder.decode(wxaccount);
    } catch (Exception e1) {
      e1.printStackTrace();
    }
    if ((StringUtils.isNotBlank(wxaccount)) && (StringUtils.isNotBlank(openid))) {
      try {
        Customer entity = this.customerService.findCustomer(wxaccount, 
          openid);

        if (entity != null)
        {
          if (request.getParameter("quan") != null)
            modelmap.addAttribute("quan", 
              request.getParameter("quan"));
          else {
            modelmap.addAttribute("quan", "");
          }

          Map<String,Object> map = new HashMap<String,Object>();
          map.put("nowtime", new Date());
          map.put("wcaccount", wxaccount);
          map.put("openid", openid);
          List<Coupon> list1 = this.couponService.selectbyzhifu(map);
          entity.setCoupon(Integer.valueOf(list1.size()));
          modelmap.addAttribute("customer", entity);
          return this.userInfourl;
        }
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
    return this.loginurl;
  }

  @RequestMapping("getVerfiyCode")
  @ResponseBody
  public Map<String, Object> getVerfiyCode(HttpServletRequest request, HttpSession session)
  {
    Map<String,Object>map = new HashMap<String,Object>();
    String phoneNum = request.getParameter("phone");

    boolean isPhone = 
      Pattern.compile(
      "^((13[0-9])|(14[012356789])|(15[012356789])|(17[0-9])|(18[0-9])|(14[57]))[0-9]{8}$")
      .matcher(phoneNum).matches();
    if (!isPhone) {
      map.put("code", Integer.valueOf(-1));
      map.put("msg", "手机号码不正确");
      return map;
    }
    Date timeoutDate = (Date)session.getAttribute("verfiycodetimeout");
    if (timeoutDate != null) {
      Date nowdate = new Date();
      int index = nowdate.compareTo(timeoutDate);
      if (index < 0)
      {
        map.put("msg", "验证码已经发送了,请耐心等待");
        return map;
      }

    }

    StringBuffer randomCode = new StringBuffer();
    for (int i = 0; i < 6; i++) {
      Random random = new Random();
      String rand = String.valueOf(random.nextInt(10));
      randomCode.append(rand);
    }
    session.removeAttribute("verfiycode");
    session.setAttribute("verfiycode", randomCode.toString());
    System.out.println("发送验证码:" + randomCode.toString());
    try {
      SenderSms.send(phoneNum, "验证码：" + randomCode.toString() + "【E爱车】");
    } catch (Exception e) {
      e.printStackTrace();
    }
    long timeout = System.currentTimeMillis() + 300000L;
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(timeout);
    Date time_date = cal.getTime();
    session.removeAttribute("verfiycodetimeout");
    session.setAttribute("verfiycodetimeout", time_date);
    map.put("code", Integer.valueOf(0));
    return map;
  }

  @RequestMapping("findByPhone")
  @ResponseBody
  public Map<String, Object> findByPhone(HttpServletRequest request, @RequestParam("wxaccount") String wxaccount, @RequestParam("openid") String openid, @RequestParam("phone") String phone)
  {
    Map map = new HashMap();
    try {
      if (StringUtils.isBlank(wxaccount)) {
        map.put("code", Integer.valueOf(-2));
        return map;
      }
      if (StringUtils.isBlank(openid)) {
        map.put("code", Integer.valueOf(-2));
        return map;
      }

      boolean isPhone = 
        Pattern.compile(
        "^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\\d{8}")
        .matcher(phone).matches();
      if (!isPhone) {
        map.put("code", Integer.valueOf(-1));
        return map;
      }
      Customer entity = this.customerService.findCustomerByPhone(wxaccount, 
        phone);
      if (entity == null) {
        map.put("code", Integer.valueOf(0));
        return map;
      }if (entity.getOpenid().equals(openid)) {
        map.put("code", Integer.valueOf(1));
        return map;
      }
      map.put("code", Integer.valueOf(2));
      return map;
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return null;
  }

  @RequestMapping({"bindPhoneNum"})
  @ResponseBody
  public Map<String, Object> bindPhoneNum(HttpServletRequest request, HttpSession session, ModelMap modelmap, Model model)
  {
    Map map = new HashMap();
    String phoneNum = request.getParameter("phone");
    String wxaccount = request.getParameter("wxaccount");
    String openid = request.getParameter("openid");
    String quan = "";

    String code = (String)session
      .getAttribute("verfiycode");
    if (StringUtils.isNotBlank(code)) {
      code = code.toLowerCase().toString();
    }

    String submitCode = WebUtils.getCleanParam(request, 
      "verfiycode");
    if (StringUtils.isNotBlank(submitCode)) {
      submitCode = submitCode.toLowerCase().toString();
    }
    if ((StringUtils.isBlank(submitCode)) || (StringUtils.isBlank(code)) || 
      (!code.equals(submitCode))) {
      map.put("code", Integer.valueOf(-1));
      map.put("msg", "验证码错误!");
      return map;
    }
    try {
      Customer entity = this.customerService.findCustomer(wxaccount, openid);
      if (entity != null) {
        if (StringUtils.isBlank(entity.getPhoneNum())) {
          entity.setPhoneNum(phoneNum);
          this.customerService.updateByPrimaryKeySelective(entity);

          Map msp = new HashMap();
          msp.put("nowtime", new Date());
          msp.put("couponZhi", Integer.valueOf(0));
          List list = this.couponService.selectbyjuan(msp);

          Map mqp = new HashMap();
          if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++)
            {
              mqp.put("wxaccount", wxaccount);
              mqp.put("openid", openid);
              mqp.put("counponid", ((Coupon)list.get(i)).getCouponId());
              Example e = new Example(Collar.class);
              e.createCriteria().andEqualTo("counponId", 
                ((Coupon)list.get(i)).getCouponId());
              List colist = this.collarService
                .selectByExample(e);
              int t = colist == null ? 0 : colist.size();
              if (t < ((Coupon)list.get(i)).getCouponCount().intValue()) {
                Collar q = this.collarService.selectbywx(mqp);
                if (q == null) {
                  Collar c = new Collar();
                  c.setId(UuidUtil.uuid().toString());
                  c.setCounponId(((Coupon)list.get(i)).getCouponId());
                  c.setCustomerId(entity.getCustomerId());
                  c.setCollarTime(new Date());
                  c.setWxaccount(wxaccount);
                  c.setOpenid(openid);
                  this.collarService.saveSelective(c);
                  quan = "1";
                }

              }

            }

          }

        }

        map.put("code", Integer.valueOf(0));
        map.put("url", 
          "/weixin/f/autoinn/user/userInfo?quan=" + quan);
        System.out.println(map.get("url"));
        return map;
      }
      map.put("code", Integer.valueOf(-1));
      map.put("msg", "未取到用户信息!");
      return map;
    }
    catch (Exception e)
    {
      e.printStackTrace();

      map.put("code", Integer.valueOf(-1));
      map.put("msg", "服务器错误,请稍候再试!");
    }return map;
  }

  @RequestMapping({"getOpenid"})
  public String wxgetToken(HttpServletRequest request, HttpServletResponse response, Model model, ModelMap modelmap)
  {
    Oauth oauthInfo = new Oauth();
    String code = request.getParameter("code");
    String state = request.getParameter("state");
    String result = "";
    try
    {
      result = oauthInfo.getToken(code);
      JSONObject token_json = JSON.parseObject(result);
      String openid = token_json.getString("openid");

      String new_opeind = Base64Coder.encoded(openid);
      CookieUtils.setCookie(response, "autoinn_session", new_opeind);

      WXAccount wxaccount = this.wxAccountService.findwxaccount(
        oauthInfo.getAppid(), oauthInfo.getSecret());
      if (wxaccount != null) {
        String new_wxaccount = Base64Coder.encoded(wxaccount
          .getAcccountId());

        Customer entity = this.customerService.findCustomer(
          wxaccount.getAcccountId(), openid);
        if (entity != null) {
          if (StringUtils.isNotBlank(entity.getPhoneNum())) {
            modelmap.addAttribute("customer", entity);

            CookieUtils.setCookie(response, "wx_session", 
              new_wxaccount);
            if (state.equals("storelist")) {
              return "redirect:/weixin/f/autoinn/xc/store";
            }
            if(state.equals("bylist")){
            	return "redirect:/weixin/f/matenance/by/brand";
            }
            if(state.equals("shlist")){
            	return "redirect:/moblile/index/main";
            }
            if(state.equals("baoxian")){
            	return "redirect:/weixin/f/autoinn/bx/userRegister";
            }
            if(state.equals("baozhu")){
            	return "redirect:/bao/index";
            }
            if(state.equals("dinglist")){
                return "redirect:/weixin/f/autoinn/xc/userpay/dinglist";
            }
            Map map = new HashMap();
            map.put("nowtime", new Date());
            map.put("wcaccount", wxaccount.getAcccountId());
            map.put("openid", openid);
            List list1 = this.couponService.selectbyzhifu(map);

            entity.setCoupon(Integer.valueOf(list1.size()));
            return this.userInfourl;
          }

          CookieUtils.setCookie(response, "wx_session", new_wxaccount);

          modelmap.addAttribute("wxaccount", 
            wxaccount.getAcccountId());
          modelmap.addAttribute("openid", openid);
        } else {
          User wxuser = new User();
          String accessToken = getExistAccessToken(wxaccount
            .getAcccountId());
          if (StringUtils.isNotBlank(accessToken)) {
            UserInfo wxUserInfo = wxuser.getUserInfo(accessToken, 
              openid);

            Customer centity = new Customer();
            centity.setCity(wxUserInfo.getCity());
            centity.setCountry(wxUserInfo.getCountry());
            centity.setProvince(wxUserInfo.getProvince());
            centity.setCustomerId(UuidUtil.uuid().toString());
            String nickName = wxUserInfo.getNickname();

            nickName = EmojiFilter.filterEmoji(nickName);
            centity.setNickname(nickName);

            centity.setOpenid(openid);
            centity.setSex(wxUserInfo.getSex()==0?"男":"女");
            centity.setStatus(Integer.valueOf(0));
            centity.setSubscribe(Integer.valueOf(wxUserInfo.getSubscribe()));
            centity.setSubscribeTime(wxUserInfo.getSubscribe_time().toString());

            centity.setSurplus(new BigDecimal(0));
            centity.setApplicationTime(new Date());
            centity.setWxAccount(wxaccount.getAcccountId());
            this.customerService.saveSelective(centity);

            if (wxUserInfo.getSubscribe() != 0)
            {
              model.addAttribute("wxaccount", 
                wxaccount.getAcccountId());
              CookieUtils.setCookie(response, "wx_session", 
                new_wxaccount);
              model.addAttribute("openid", openid);
              modelmap.addAttribute("wxaccount", 
                wxaccount.getAcccountId());
              modelmap.addAttribute("openid", openid);
            }
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return this.loginurl;
  }

  public String getExistAccessToken(String wxaccount)
  {
    String token = null;
    try {
      WXaccesstoken wxaccesstoken = 
        (WXaccesstoken)this.wxaccesstokenService
        .selectByPrimaryKey(wxaccount);
      if (wxaccesstoken != null)
      {
        token = wxaccesstoken.getAccesstoken();
        Date accessExpires = wxaccesstoken.getAccessexpires();
        Date nowdate = new Date();
        int index = nowdate.compareTo(accessExpires);
        System.out.println("index>0:" + (index > 0));
        if (index > 0)
          token = getNewAccesstoken(wxaccount, false);
      }
      else
      {
        token = getNewAccesstoken(wxaccount, true);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return token;
  }

  public String getNewAccesstoken(String wxAccount, boolean isNew)
  {
    String token = null;
    try {
      token = WeChat.getAccessToken();
      if (StringUtils.isNotBlank(token)) {
        WXaccesstoken entity = new WXaccesstoken();
        entity.setAccesstoken(token);
        long timeout = System.currentTimeMillis() + 7200000L;
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(timeout);
        Date time_date = cal.getTime();
        entity.setAccessexpires(time_date);
        entity.setWxAccount(wxAccount);
        if (isNew)
          this.wxaccesstokenService.save(entity);
        else
          this.wxaccesstokenService.updateByPrimaryKey(entity);
      }
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return token;
  }
}